package org.shopen.puremvc.model.domain.testing
{
	import mx.collections.ArrayCollection;
	
	import org.shopen.puremvc.model.domain.ISerializable;
	import org.shopen.puremvc.model.utils.Convert;
	import org.shopen.puremvc.model.utils.GUID;
	import org.shopen.puremvc.model.utils.Random;

	public class Testing implements ISerializable
	{
		[Bindable]
		private var _id : String = "";
		[Bindable]
		public function get id() : String
		{
			return _id;
		}
		public function set id(value : String) : void
		{
			_id = value;
		}
		
		[Bindable]
		private var _title : String = "";
		[Bindable]
		public function get title() : String
		{
			return _title;
		}
		public function set title(value : String) : void
		{
			_title = value;
		}
		
		[Bindable]
		private var _randomNumber : Number;
		[Bindable]
		public function get randomNumber() : Number
		{
			return _randomNumber;
		}
		public function set randomNumber(value : Number) : void
		{
			_randomNumber = value;
		}
		
		[Bindable]
		private var _maxPoints : Number;
		[Bindable]
		public function get maxPoints() : Number
		{
			return _maxPoints;
		}
		public function set maxPoints(value : Number) : void
		{
			_maxPoints = value;
		}
		
		[Bindable]
		private var _tests : ArrayCollection = new ArrayCollection();
		[Bindable]
		public function get tests() : ArrayCollection
		{
			return _tests;
		}
		public function set tests(value : ArrayCollection) : void
		{
			_tests = value;
		}
		
		public function get sumPoints() : Number
		{
			var result : Number = 0;
			for each (var test : Test in tests)
			{
				result += test.points;
			}
			return result;
		}
		
		public function Testing(node : XML = null)
		{
			if (node != null)
			{
				deserialize(node);
			}
		}

		public function deserialize(node:XML):void
		{
			if ("@id" in node)
			{
				id = Convert.toString(node.@id);
			}
			if ("@title" in node)
			{
				title = Convert.toString(node.@title);
			}
			if ("@randomnumber" in node)
			{
				randomNumber = Convert.toNumber(node.@randomnumber);
			}
			if ("@maxpoints" in node)
			{
				maxPoints = Convert.toNumber(node.@maxpoints);
			}
			
			var testList : XMLList = node..test;
			tests = new ArrayCollection();
			for each(var testNode : XML in testList)
			{
				var test : Test = null
				if ("@type" in testNode)
				{
					var testType : String = Convert.toString(testNode.@type);
					test = TestFactory.createTest(testType, testNode);
				}
				else
				{
					test = TestFactory.createTest(TestFactory.DEFAULT_TEST, testNode);
				}
				tests.addItem(test);
			}
		}
		
		public function serialize():XML
		{
			// TODO: consider implement if needed.
			return null;
		}
		
		public function getRandomTesting() : Testing
		{
			var result : Testing = this.clone();
			var random : Number;
			var randomTest : Test;
			var testsColl : ArrayCollection = new ArrayCollection();
			for (var i : Number = 0; i<randomNumber && tests.length > 0; ++i)
			{
				random = Random.getRandomNumber(0, this.tests.length-1);
				randomTest = tests.removeItemAt(random) as Test;
				testsColl.addItem(randomTest);
			}
			
			result.tests = testsColl;
			
			result.normalizePoints();
			return result;
		}
		
		public function clone() : Testing
		{
			var result : Testing = new Testing();
			result.title = this.title;
			result.id = this.id + GUID.create().substr(0, 8);
			result.maxPoints = this.maxPoints;
			result.randomNumber = this.randomNumber;
			result.tests = new ArrayCollection();
			for each (var test : Test in this.tests)
			{
				result.tests.addItem(test.clone());
			}
			
			return result;
		}
		
		public function normalizePoints() : void
		{
			var coef : Number = maxPoints/sumPoints;
			
			for each(var test : Test in tests)
			{
				test.points *= coef;
			}
		}
		
	}
}